编程上下文中，反射指的是以编程方式检查程序特性的能力(例如，回答诸如类型是整数吗？或类类型包含哪些非静态数据成员？)元编程是“对程序进行编程”的技巧，相当于以编程方式生成新代码。因此，反射式元编程是一种自动合成代码，使其适应程序的现有属性(通常是类型)的技术。

本书的第三部分中，我们将探讨模板如何实现一些简单形式的反射和元编程(某种意义上，模板实例化是元编程的一种形式，因为它会导致新代码的合成)。然而，当涉及到反射时，C++17模板的能力是相当有限的(例如，不可能回答这个问题:一个类类型包含哪些非静态数据成员？)，元编程的选项不是很方便(特别是，语法变得笨拙，性能令人失望)。

认识到这一领域新特性的潜力，C++标准化委员会创建了一个研究小组(SG7)，以探索更强大的反射选项。组织的章程后来也扩展到元编程，以下是正在考虑的选项的一个例子:

\begin{lstlisting}[style=styleCXX]
template<typename T> void report(T p) {
	constexpr {
		std::meta::info infoT = reflexpr(T);
		for (std::meta::info : std::meta::data_members(infoT)) {
			-> {
				std::cout << (: std::meta::name(info) :)
				<< ": " << p.(.info.) << ’\n’;
			}
		}
	}
	// code will be injected here
}
\end{lstlisting}

这段代码中有很多新内容。首先，constexpr{…}构造强制其中的语句在编译时进行求值，但若出现在模板中，则只在模板实例化时进行求值。其次，reflexpr()操作符会生成一个不透明类型std::meta::info的表达式，这是一个句柄，用于反映关于其参数的信息(在本例中是T的类型)。标准元函数库允许查询此元信息。标准元函数之一是std::meta::data\_members，会生成一个std::meta::info序列，描述其操作数的直接非静态数据成员。所以上面的for循环实际上是对p的非静态数据成员的循环。

该系统元编程能力的核心是在各种范围内“注入”代码的能力。构造\texttt{->}{…}在启动constexpr求值的语句或声明之后，注入语句和/或声明。本例中，在constexpr{…}构造。注入的代码片段可以包含特定的模式，这些模式可以使用计算值替换。这个例子中，(:…:)产生了一个字符串字面值(表达式std::meta::name(info)产生了一个类似字符串的对象，表示实体数据成员的非限定名，在这个例子中由info表示)。类似地，表达式(.info.)产生一个标识符，命名info所表示的实体。还提出了用于生成类型、模板参数列表等的其他模式。

这些就绪之后，实例化类型的函数模板report():

\begin{lstlisting}[style=styleCXX]
struct X {
	int x;
	std::string s;
};
\end{lstlisting}

会产生类似于

\begin{lstlisting}[style=styleCXX]
template<> void report(X const& p) {
	std::cout << "x" << ": " << "p.x" << ’\n’;
	std::cout << "s" << ": " << "p.s" << ’\n’;
}
\end{lstlisting}

该函数自动生成一个函数来输出类类型的非静态数据成员值。

这些类型的功能有许多应用程序。虽然类似的东西很可能最终会采纳到语言中，但还不清楚什么时候采用。在撰写本文时已经演示了一些实验性实现。(出版这本书之前，SG7同意使用constexpr求值和类似std::meta::info的值类型来处理反射式元编程。然而，这里提出的注入机制没有达成一致意见，可能会采取另一种方式)

























